/******************************************************************************

  COMPILE USAGE : -lreadline -ltermcap 
******************************************************************************/
#ifndef UTIL_H
#define UTIL_H

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cassert>

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::map;

//=== Util function ===========================================================
//
//=============================================================================
extern bool fileExists( const string & str );
/******************************************************************************

format: 
   
usage :
   construct    ArgAnalyzer( format ,argc, argv )
   arg[int] <-- to get the nessceary main option with order

example: 
   char * usage = " run <file:path> [-out <out:path> ]";
   ArgAnalyzer arg ( usage , argc , argv );
   string outpath = arg["-out"].setted?arg["-out"][0]:"";
   string inpath = arg[0];

******************************************************************************/
class ArgAnalyzer
{
  friend class JCmdMgr;
  class Option
  {
  public:
    Option ()
    {
      setted = false;
    }
    bool setted;
      vector < string > arg;
      vector < string > type;
      vector < string > description;
    void print ();
    unsigned size ()
    {
      return arg.size ();
    }
    const char *operator[] (unsigned i)
    {
      return arg[i].c_str ();
    }
  };

  map < string, Option * >_opts;
  string _program;
  Option _main;
  string _usage;

private:

  void construct (const char *);
  void optfield (Option *, const char *);
  void option (const char *);

public:
  ArgAnalyzer (const char *, unsigned, const char **);
  int parse (unsigned argc, const char **argv);
  ArgAnalyzer (const char *);
  ~ArgAnalyzer ();
  //const string & spec()const{return _usage;}
  void usage ()
  {
    cout << _usage << endl;
  }
  void print ();
  Option & operator[](string str)
  {
    if (_opts.find (str) == _opts.end ())
      {
	cout << "ERROR " << endl;
	exit (0);
      }
    return *(_opts[str]);
  }
  string operator[] (int i)
  {
    return _main[i];
  }
  static unsigned MODE; // 0 : if error exit 1: if error return 
};
#endif
